﻿using System;
using System.Web;
using System.Web.Http;
using System.Web.Routing;
using Altairis.Web;

namespace Altairis.FluffyCloud.WebCore {

    internal static class RouteConfig {
        private const string FORMAT_EMAIL = @"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
        private const string FORMAT_GUID = @"^[0-9a-f]{32}$";
        private const string FORMAT_NUMBER = @"^\d+$";
        private const string FORMAT_ROLE_NAME = @"^([A-Za-z][A-Za-z0-9_]{2,24})?\$[A-Za-z0-9]+$";
        private const string FORMAT_SECURITY_CODE = @"^[A-Za-z0-9-_]{43}$";
        private const string FORMAT_USER_NAME = @"^[A-Za-z][A-Za-z0-9_]{2,24}$";

        public static void RegisterRoutes(RouteCollection routes) {
            // General and utility
            routes.MapPageRoute("HomePage", "", "~/Pages/HomePage.aspx", false);

            // Registration and account management
            RouteTable.Routes.MapPageRoute("RegStep1", "reg", "~/Pages/Account/Registration.aspx", false);
            RouteTable.Routes.MapPageRoute("RegStep3", "reg/{email}/{code}", "~/Pages/Account/Registration.aspx", false,
                null,
                new RouteValueDictionary(new { email = FORMAT_EMAIL }));
            RouteTable.Routes.MapPageRoute("PwResetStep1", "reset", "~/Pages/Account/PasswordReset.aspx");
            RouteTable.Routes.MapPageRoute("PwResetStep3", "reset/{userName}/{code}", "~/Pages/Account/PasswordReset.aspx", false,
                null,
                new RouteValueDictionary(new { username = FORMAT_USER_NAME }));
            RouteTable.Routes.MapPageRoute("Login", "login", "~/Pages/Account/Login.aspx", false);
            RouteTable.Routes.MapHttpHandler<Handlers.LogoutHandler>("Logout", "logout");

            // Personalized user pages
            routes.MapPageRoute("MyHome", "my", "~/Pages/My/HomePage.aspx", false);
            routes.MapPageRoute("MyProfile", "my/profile", "~/Pages/My/Profile.aspx", false);
            routes.MapPageRoute("MyProfileAcl", "my/profile/acl", "~/Pages/My/ProfileAcl.aspx", false);
            routes.MapPageRoute("MySettings", "my/settings", "~/Pages/My/Settings.aspx", false);
            routes.MapPageRoute("MyPassword", "my/password", "~/Pages/My/Password.aspx", false);
            routes.MapPageRoute("MyEmail", "my/email", "~/Pages/My/Email.aspx", false);
            routes.MapPageRoute("MyMessages", "my/messages/{pageIndex}", "~/Pages/My/Messages.aspx", false,
                new RouteValueDictionary(new { pageIndex = "1" }),
                new RouteValueDictionary(new { pageIndex = FORMAT_NUMBER }));
            routes.MapPageRoute("MyUserMessages", "my/messages/{userName}/{pageIndex}", "~/Pages/My/Messages.aspx", false,
                new RouteValueDictionary(new { pageIndex = "1" }),
                new RouteValueDictionary(new { pageIndex = FORMAT_NUMBER, userName = FORMAT_USER_NAME }));
            routes.MapHttpHandler<Handlers.MessagesFeedHandler>("MyMessagesFeed", "feeds/{securityCode}/mailbox.rss",
                null,
                new RouteValueDictionary(new { securityCode = FORMAT_SECURITY_CODE }));
            routes.MapHttpHandler<Handlers.MessagesFeedHandler>("MyUserMessagesFeed", "feeds/{securityCode}/{userName}/mailbox.rss",
                null,
                new RouteValueDictionary(new { securityCode = FORMAT_SECURITY_CODE, userName = FORMAT_USER_NAME }));
            routes.MapHttpHandler<Handlers.TopicFeedHandler>("MyTopicFeed", "feeds/{securityCode}/topic-{topicId}.rss",
                new RouteValueDictionary(new { securityCode = FORMAT_SECURITY_CODE, topicId = FORMAT_NUMBER }));

            // Groups
            routes.MapPageRoute("GroupList", "groups", "~/Pages/Groups/HomePage.aspx", false);
            routes.MapPageRoute("GroupCreate", "groups/create", "~/Pages/Groups/Detail.aspx", false);
            routes.MapPageRoute("GroupDetail", "groups/{rolename}", "~/Pages/Groups/Detail.aspx", false,
                null,
                new RouteValueDictionary(new { rolename = FORMAT_ROLE_NAME }));

            // Forum
            routes.MapPageRoute("ForumList", "forum", "~/Pages/Forum/HomePage.aspx", false);
            routes.MapPageRoute("ForumCreate", "forum/create", "~/Pages/Forum/Create.aspx", false);
            routes.MapPageRoute("ForumDetail", "forum/{id}/{pageIndex}", "~/Pages/Forum/Detail.aspx", false,
                new RouteValueDictionary(new { pageIndex = "1" }),
                new RouteValueDictionary(new { id = FORMAT_NUMBER, pageIndex = FORMAT_NUMBER }));
            routes.MapPageRoute("ForumSettings", "forum/{id}/settings", "~/Pages/Forum/Settings.aspx", false,
                null,
                new RouteValueDictionary(new { id = FORMAT_NUMBER }));
            routes.MapPageRoute("ForumAcl", "forum/{id}/acl", "~/Pages/Forum/Acl.aspx", false,
                null,
                new RouteValueDictionary(new { id = FORMAT_NUMBER }));
            routes.MapPageRoute("ForumEditPost", "forum/{topicId}/{postId}", "~/Pages/Forum/EditPost.aspx", false,
                null,
                new RouteValueDictionary(new { topicid = FORMAT_NUMBER, postid = FORMAT_GUID }));

            // Users
            routes.MapPageRoute("Users", "users/{pageIndex}", "~/Pages/Users/HomePage.aspx", false,
                new RouteValueDictionary(new { pageIndex = "1" }),
                new RouteValueDictionary(new { pageIndex = FORMAT_NUMBER }));
            routes.MapPageRoute("UserProfile", "users/{userName}", "~/Pages/Users/Profile.aspx", false,
                null,
                new RouteValueDictionary(new { username = FORMAT_USER_NAME }));
            routes.MapHttpHandler<Handlers.UserIconHandler>("UserIcon", "users/{userName}/icon/{iconSize}",
                new RouteValueDictionary(new { iconSize = "150" }),
                new RouteValueDictionary(new { userName = FORMAT_USER_NAME, iconSize = FORMAT_NUMBER }));

            // Gallery
            //routes.MapPageRoute("Gallery", "gallery", "~/Pages/Gallery/HomePage.aspx");

            // Blog
            //routes.MapPageRoute("Blog", "blog", "~/Pages/Blog/HomePage.aspx");

            // Wiki
            RouteTable.Routes.MapPageRoute("WikiSandbox", "wiki/sandbox", "~/Pages/Sewen/Sandbox.aspx", false);
            RouteTable.Routes.MapPageRoute("WikiPreview", "wiki/preview", "~/Pages/Sewen/Preview.aspx", false);
            RouteTable.Routes.MapPageRoute("WikiPage", "wiki/{slug}", "~/Pages/Sewen/WikiPage.aspx", false,
                new RouteValueDictionary(new { slug = "FAQ" }));
            RouteTable.Routes.MapPageRoute("WikiPageEdit", "admin/wiki/edit/{slug}", "~/Pages/Sewen/PageEdit.aspx", false);
            RouteTable.Routes.MapPageRoute("WikiPageHistory", "admin/wiki/history/{slug}", "~/Pages/Sewen/History.aspx", false);
            RouteTable.Routes.MapPageRoute("WikiPageVersion", "admin/wiki/history/{slug}/{version}", "~/Pages/Sewen/WikiPage.aspx", false, 
                null, 
                new RouteValueDictionary(new { version = new VersionRouteConstraint() }));
            RouteTable.Routes.MapPageRoute("WikiPageNew", "admin/wiki/new", "~/Pages/Sewen/PageNew.aspx", false);

            // API and such
            routes.MapHttpHandler<Handlers.HeaderImageIndexHandler>("Content/HeaderImages/list.json");
            routes.MapHttpRoute("API", "api/{controller}/{id}", new { id = RouteParameter.Optional });
        }

        private class VersionRouteConstraint : IRouteConstraint {

            public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
                var val = values[parameterName] as string;
                DateTime dt;
                return DateTime.TryParseExact(val, "yyyyMMddHHmmssfff", null, System.Globalization.DateTimeStyles.AssumeLocal, out dt);
            }
        }
    }
}